
package org.nViron.Render;

import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import org.nViron.nvRender.nvFrustum;
import org.nViron.nvRender.nvVec3;

/**
 * OpenGL 1.2 implementation of nvFrustums render code based on JOGL
 * @author Roland Haring <p>
 * <script type="text/javascript" src="http://www.ohloh.net/p/376434/widgets/project_basic_stats.js"></script>
 */
public class FrustumGL extends nvFrustum {

    private GLAutoDrawable drawable;

    public FrustumGL(GLAutoDrawable drawable) {
        super();
        this.drawable = drawable;
    }

    void drawPoints() {
        GL gl = drawable.getGL();
        gl.glBegin(gl.GL_POINTS);

        gl.glVertex3f(ntl.x, ntl.y, ntl.z);
        gl.glVertex3f(ntr.x, ntr.y, ntr.z);
        gl.glVertex3f(nbl.x, nbl.y, nbl.z);
        gl.glVertex3f(nbr.x, nbr.y, nbr.z);

        gl.glVertex3f(ftl.x, ftl.y, ftl.z);
        gl.glVertex3f(ftr.x, ftr.y, ftr.z);
        gl.glVertex3f(fbl.x, fbl.y, fbl.z);
        gl.glVertex3f(fbr.x, fbr.y, fbr.z);

        gl.glEnd();
    }

    void drawLines() {
        GL gl = drawable.getGL();
        gl.glBegin(gl.GL_LINE_LOOP);
        //near plane
        gl.glVertex3f(ntl.x, ntl.y, ntl.z);
        gl.glVertex3f(ntr.x, ntr.y, ntr.z);
        gl.glVertex3f(nbr.x, nbr.y, nbr.z);
        gl.glVertex3f(nbl.x, nbl.y, nbl.z);
        gl.glEnd();

        gl.glBegin(gl.GL_LINE_LOOP);
        //far plane
        gl.glVertex3f(ftr.x, ftr.y, ftr.z);
        gl.glVertex3f(ftl.x, ftl.y, ftl.z);
        gl.glVertex3f(fbl.x, fbl.y, fbl.z);
        gl.glVertex3f(fbr.x, fbr.y, fbr.z);
        gl.glEnd();

        gl.glBegin(gl.GL_LINE_LOOP);
        //bottom plane
        gl.glVertex3f(nbl.x, nbl.y, nbl.z);
        gl.glVertex3f(nbr.x, nbr.y, nbr.z);
        gl.glVertex3f(fbr.x, fbr.y, fbr.z);
        gl.glVertex3f(fbl.x, fbl.y, fbl.z);
        gl.glEnd();

        gl.glBegin(gl.GL_LINE_LOOP);
        //top plane
        gl.glVertex3f(ntr.x, ntr.y, ntr.z);
        gl.glVertex3f(ntl.x, ntl.y, ntl.z);
        gl.glVertex3f(ftl.x, ftl.y, ftl.z);
        gl.glVertex3f(ftr.x, ftr.y, ftr.z);
        gl.glEnd();

        gl.glBegin(gl.GL_LINE_LOOP);
        //left plane
        gl.glVertex3f(ntl.x, ntl.y, ntl.z);
        gl.glVertex3f(nbl.x, nbl.y, nbl.z);
        gl.glVertex3f(fbl.x, fbl.y, fbl.z);
        gl.glVertex3f(ftl.x, ftl.y, ftl.z);
        gl.glEnd();

        gl.glBegin(gl.GL_LINE_LOOP);
        // right plane
        gl.glVertex3f(nbr.x, nbr.y, nbr.z);
        gl.glVertex3f(ntr.x, ntr.y, ntr.z);
        gl.glVertex3f(ftr.x, ftr.y, ftr.z);
        gl.glVertex3f(fbr.x, fbr.y, fbr.z);
        gl.glEnd();
    }

    void drawPlanes() {
        GL gl = drawable.getGL();
        gl.glBegin(gl.GL_QUADS);

        //near plane
        gl.glVertex3f(ntl.x, ntl.y, ntl.z);
        gl.glVertex3f(ntr.x, ntr.y, ntr.z);
        gl.glVertex3f(nbr.x, nbr.y, nbr.z);
        gl.glVertex3f(nbl.x, nbl.y, nbl.z);

        //far plane
        gl.glVertex3f(ftr.x, ftr.y, ftr.z);
        gl.glVertex3f(ftl.x, ftl.y, ftl.z);
        gl.glVertex3f(fbl.x, fbl.y, fbl.z);
        gl.glVertex3f(fbr.x, fbr.y, fbr.z);

        //bottom plane
        gl.glVertex3f(nbl.x, nbl.y, nbl.z);
        gl.glVertex3f(nbr.x, nbr.y, nbr.z);
        gl.glVertex3f(fbr.x, fbr.y, fbr.z);
        gl.glVertex3f(fbl.x, fbl.y, fbl.z);

        //top plane
        gl.glVertex3f(ntr.x, ntr.y, ntr.z);
        gl.glVertex3f(ntl.x, ntl.y, ntl.z);
        gl.glVertex3f(ftl.x, ftl.y, ftl.z);
        gl.glVertex3f(ftr.x, ftr.y, ftr.z);

        //left plane

        gl.glVertex3f(ntl.x, ntl.y, ntl.z);
        gl.glVertex3f(nbl.x, nbl.y, nbl.z);
        gl.glVertex3f(fbl.x, fbl.y, fbl.z);
        gl.glVertex3f(ftl.x, ftl.y, ftl.z);

        // right plane
        gl.glVertex3f(nbr.x, nbr.y, nbr.z);
        gl.glVertex3f(ntr.x, ntr.y, ntr.z);
        gl.glVertex3f(ftr.x, ftr.y, ftr.z);
        gl.glVertex3f(fbr.x, fbr.y, fbr.z);

        gl.glEnd();
    }

    void drawNormals() {
        GL gl = drawable.getGL();
        nvVec3 a, b;

        gl.glBegin(gl.GL_LINES);

        // near
        a = (ntr.add(ntl.add(nbr.add(nbl)))).mul(0.25f);
        b = a.add(pl[NEARP].normal);
        gl.glVertex3f(a.x, a.y, a.z);
        gl.glVertex3f(b.x, b.y, b.z);

        // far
        a = (ftr.add(ftl.add(fbr.add(fbl)))).mul(0.25f);
        b = a.add(pl[FARP].normal);
        gl.glVertex3f(a.x, a.y, a.z);
        gl.glVertex3f(b.x, b.y, b.z);

        // left
        a = (ftl.add(fbl.add(nbl.add(ntl)))).mul(0.25f);
        b = a.add(pl[LEFT].normal);
        gl.glVertex3f(a.x, a.y, a.z);
        gl.glVertex3f(b.x, b.y, b.z);

        // right
        a = (ftr.add(nbr.add(fbr.add(ntr)))).mul(0.25f);
        b = a.add(pl[RIGHT].normal);
        gl.glVertex3f(a.x, a.y, a.z);
        gl.glVertex3f(b.x, b.y, b.z);

        // top
        a = (ftr.add(ftl.add(ntr.add(ntl)))).mul(0.25f);
        b = a.add(pl[TOP].normal);
        gl.glVertex3f(a.x, a.y, a.z);
        gl.glVertex3f(b.x, b.y, b.z);

        // bottom
        a = (fbr.add(fbl.add(nbr.add(nbl)))).mul(0.25f);
        b = a.add(pl[BOTTOM].normal);
        gl.glVertex3f(a.x, a.y, a.z);
        gl.glVertex3f(b.x, b.y, b.z);

        gl.glEnd();
    }
}
